package com.zhongan.gateway.filter;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.zhongan.dsf.config.ConsumerConfig;
import com.zhongan.dsf.consumer.DefaultGenericService;
import com.zhongan.dsf.consumer.GenericService;
import com.zhongan.dsf.core.Response;
import com.zhongan.dsf.spring.DSFServer;
import com.zhongan.gateway.bean.Api;
import com.zhongan.gateway.bean.ApiAttribute;
import com.zhongan.gateway.common.constant.GwDeveloperApiConstant;
import com.zhongan.gateway.common.enums.GatewayErrorCodeEnum;
import com.zhongan.gateway.common.exception.GatewayException;
import com.zhongan.gateway.common.utils.TypeUtil;
import com.zhongan.gateway.dto.RequestBase;
import com.zhongan.gateway.service.ApiService;

/**
 * api调用次数记录
 */
@Component
public class RoutDubboZuulFilter extends ZuulFilter {

    private Logger     logger = LoggerFactory.getLogger(RoutDubboZuulFilter.class);
    //    private static Map<String, GenericService> services = new ConcurrentHashMap<String, GenericService>();

    @Resource
    private ApiService apiService;

    @Autowired
    private DSFServer  dSFServer;

    @Value("${dsf.serialization}")
    private String     serialization;

    @Override
    public String filterType() {
        return "route";
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String serviceId = (String) ctx.get("serviceId");

        Api api = (Api) ctx.getRequest().getAttribute("api");
        String serviceType = api.getServiceType();
        return "gw".equals(serviceId) && ctx.sendZuulResponse()
                && GwDeveloperApiConstant.SERVICETYPE_DUBBO.equals(serviceType);

    }

    @Override
    public Object run() {

        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();
        RequestBase re = (RequestBase) request.getAttribute("requestBase");

        JSONObject biz = (JSONObject) re.getBizContent();
        //发起http请求
        Api api = (Api) request.getAttribute("api");
        List<ApiAttribute> list = apiService.selectApiAttrs(api.getId());
        GenericService genericService = getGenericService(api);
        //组装参数
        Object[] params = getDubboParam(list, biz);
        long start = System.currentTimeMillis();
        logger.info("开始调用dsf服务...interface={} ,method={}", api.getInterfaceName(), api.getMethod());
        Response invokedResult = null;
        try {
            invokedResult = genericService.invoke(api.getMethod(), (String[]) params[0], (Object[]) params[1]);
        } catch (Throwable e) {
            logger.error("invoke dsf error:" + e.getMessage(), e);
        }
        logger.info("结束调用dsf服务...timecost={}", System.currentTimeMillis() - start);
        String res = "";
        if (null != invokedResult) {
            if (null != invokedResult.getException()) {

                request.setAttribute("gatewayException",
                        new GatewayException(GatewayErrorCodeEnum.INVOKE_ERROR.getCode(), invokedResult.getException()
                                .getMessage()));
                throw new RuntimeException();
            } else {
                res = TypeUtil.initDsfStr(invokedResult.getResult().toString());
            }
        }

        if (!StringUtils.isEmpty(res)) {
            context.set("res", res);
        }
        context.setSendZuulResponse(false);
        logger.info("完成Route Http...");

        return null;

    }

    private GenericService getGenericService(Api api) {

        //        String serviceKey = api.getServiceName() + "_" + api.getVersion();
        //        GenericService service = services.get(serviceKey);
        //        if (service != null) {
        //            return service;
        //        }
        GenericService service = new DefaultGenericService();
        ConsumerConfig config = new ConsumerConfig();
        config.setInterfaceName(api.getInterfaceName());
        config.setConnectTimeoutMillis(api.getTimeout());
        config.setSerialization(serialization);
        service.setConsumerConfig(config);

        service.setRegister(dSFServer.getRegister());
        //        if (service != null) {
        //            services.put(serviceKey, service);
        //        }
        return service;
    }

    private Object[] getDubboParam(List<ApiAttribute> list, JSONObject biz) {
        Object[] objs = new Object[2];
        if (null != list && !list.isEmpty()) {
            int size = list.size();
            String[] paramTypes = new String[size];
            Object[] paramValues = new Object[size];
            for (int i = 0; i < size; i++) {
                ApiAttribute aa = list.get(i);
                String type = aa.getAttributeType();
                paramTypes[i] = type;
                //dsf只有一个string格式的参数，就是biz的整体
                paramValues[i] = biz.toJSONString();
                //                paramValues[i] = biz.get(aa.getName());
                //                if (size == 1 && type != null && type.startsWith("com.")) {
                //                    //
                //                    paramValues[i] = biz;
                //                } else {
                //                    paramValues[i] = biz.get(aa.getName());
                //                }

            }
            objs[0] = paramTypes;
            objs[1] = paramValues;
        }
        return objs;
    }

}
